

#ifndef COLLECTD_COMMTRAFF_H
#define COLLECTD_COMMTRAFF_H


#include <stdint.h>
#include <time.h>
#include <net/if.h>
#include <netinet/in.h>

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif

#define COLLECTD_SERVER_PORT 49999
#define ONCE_RECORD_NUMS 350

#define PLUGIN_NAME "commtraff"

#define RPC_DS_NAME "rpcTraff"
#define TRANSPORT_DS_NAME "transportTraff"
#define SESSION_DS_NAME "sessionTraff"
#define WPA_DS_NAME "wpaTraff"
#define LINK_DS_NAME "if_values"
#define HISYSEVENT_DS_NAME "hisysevent"

// 插入流量记录时是否在日志里打印记录信息
#define IS_PRINT_KEY "isPrintCommTraff"
// 批量插入阈值
#define BATCH_INSERT_THRESHOLD_KEY "batchInsertThreshold"
// 数据库记录保存时间
#define RECORD_STORAGE_TIME_KEY "recordStorageTime"

#define SESSION_NAME_LEN 16
#define COMMTRAFF_UDID_HASH_LEN 5

// 添加指令类型枚举
typedef enum {
    COMMTRAFF_CMD_INSERT_DATA = 1,        // 插入数据指令
    COMMTRAFF_CMD_QUERY_DATABASE,         // 数据库查询指令
    COMMTRAFF_CMD_QUERY_RESULT,                // 查询结果
} CommTraffCommandType;

typedef enum {
    COMMTRAFF_SUCCESS = 0,
    COMMTRAFF_FAIL = -999,
    COMMTRAFF_INIT_FAIL,
    COMMTRAFF_INVALID_PARAM,
    COMMTRAFF_MEM_ALLOC_FAIL,

    COMMTRAFF_NO_RRD_FILE,
    COMMTRAFF_NO_PERMISSION,
    COMMTRAFF_OPEN_DIR_FAIL,

    COMMTRAFF_NULL_PTR,
    COMMTRAFF_UV_WORK_FAIL,

} CommTraffErrCode;

typedef enum {
    TIME_RANGE_NOW,           // 现在
    TIME_RANGE_LAST_1_HOUR,   // 过去1小时
    TIME_RANGE_LAST_2_HOURS,  // 过去2小时
    TIME_RANGE_LAST_3_HOURS,  // 过去3小时
    TIME_RANGE_LAST_4_HOURS,  // 过去4小时
    TIME_RANGE_LAST_5_HOURS,  // 过去5小时
    TIME_RANGE_LAST_6_HOURS,  // 过去6小时
    TIME_RANGE_LAST_7_HOURS,  // 过去7小时
    TIME_RANGE_LAST_8_HOURS,  // 过去8小时
    TIME_RANGE_LAST_9_HOURS,  // 过去9小时
    TIME_RANGE_LAST_10_HOURS, // 过去10小时
    TIME_RANGE_LAST_11_HOURS, // 过去11小时
    TIME_RANGE_LAST_12_HOURS, // 过去12小时
    TIME_RANGE_LAST_13_HOURS, // 过去13小时
    TIME_RANGE_LAST_14_HOURS, // 过去14小时
    TIME_RANGE_LAST_15_HOURS, // 过去15小时
    TIME_RANGE_LAST_16_HOURS, // 过去16小时
    TIME_RANGE_LAST_17_HOURS, // 过去17小时
    TIME_RANGE_LAST_18_HOURS, // 过去18小时
    TIME_RANGE_LAST_19_HOURS, // 过去19小时
    TIME_RANGE_LAST_20_HOURS, // 过去20小时
    TIME_RANGE_LAST_21_HOURS, // 过去21小时
    TIME_RANGE_LAST_22_HOURS, // 过去22小时
    TIME_RANGE_LAST_23_HOURS, // 过去23小时
    TIME_RANGE_LAST_24_HOURS  // 过去24小时
} TimeRange;

typedef enum {
    LINK_LAYER_DATA,
    TRANSPORT_LAYER_DATA,
    SESSION_LAYER_DATA,
    RPC_LAYER_DATA,
    WPA_LAYER_DATA,
    HISYSEVENT_DATA
} TraffType;

// SessionType 枚举
typedef enum {
    INNER_SESSION,
    BYTE_SESSION,
    MESSAGE_SESSION,
    STREAM_SESSION,
    FILE_SESSION
} CommTraffSessionType;

typedef enum {
    PROTOCOL_TYPE_TCP = 0,  // TCP协议
    PROTOCOL_TYPE_UDP,      // UDP协议
    PROTOCOL_TYPE_BLE_GATT_CLIENT,
    PROTOCOL_TYPE_BLE_GATT_SERVER,
    PROTOCOL_TYPE_BR_A2DP_SOURCE
} CommTraffProtocolType;

// SessionTraff 结构体 (dsoftbus call)
typedef struct {
    uint8_t localSessionName[SESSION_NAME_LEN];      // 本端会话名称
    uint8_t peerSessionName[SESSION_NAME_LEN];       // 对端会话名称
    uint8_t peerUdidHash[COMMTRAFF_UDID_HASH_LEN];             // 对端UDID 4个字节的哈希
    uint16_t pid;            // 进程ID，默认值为0
    time_t time;           // 时间戳
    int32_t  handle;         // fd或者是蓝牙框架gatt返回的handle
    uint32_t channelId;      // 通道ID
    uint32_t connId;         // 连接ID
    uint32_t sessionId;      // 会话ID
    CommTraffSessionType sessionType; // 会话类型
    uint32_t sendBytes;      // 发送字节数
    uint32_t recvBytes;      // 接收字节数
} SessionTraff; //

// TransportTraff 结构体 (bt、netmanager call)
typedef struct {
    uint8_t ifName[IF_NAMESIZE];    // 接口名称
    char local[INET6_ADDRSTRLEN];       // 源地址（MAC地址）
    char remote[INET6_ADDRSTRLEN];      // 目的地址（MAC地址）
    uint16_t pid;                   // 进程ID，默认值为0
    time_t time;                  // 时间戳
    uint32_t sockId;                // 套接字ID
    CommTraffProtocolType protocol;               // 协议类型
    uint64_t sendBytes;             // 发送字节数
    uint64_t sendPacks;             // 发送包数
    uint64_t recvBytes;             // 接收字节数
    uint64_t recvPacks;             // 接收包数
} TransportTraff;

// LinkTraff 结构体
typedef struct {
    uint8_t ifName[IF_NAMESIZE];  // 接口名称
    time_t time;                  // 时间戳
    uint64_t txBytes;             // 发送字节数
    uint64_t txPackets;           // 发送包数
    uint64_t rxBytes;             // 接收字节数
    uint64_t rxPackets;           // 接收包数
    uint64_t rxErrPackets;        // 错误包数
    uint64_t txErrPackets;        // 错误包数
    uint64_t rxDropPackets;       // 丢弃包数
    uint64_t txDropPackets;       // 丢弃包数
} LinkTraff;

typedef struct {
   int32_t proxyHandle;
   int32_t stubHandle;
   uint32_t sendDataLen;
   uint32_t recvDataLen;
   uint64_t recvDataSeq;
   uint64_t sendDataSeq;
   time_t time;                  // 时间戳
   pid_t localpid;               //本端进程id
   uid_t localuid;               //本端userid
   pid_t peerpid;                //对端进程id
   uid_t peeruid;                //对端userid
} RpcTraff;

typedef struct{
    uint8_t ifName[IF_NAMESIZE];    //接口名称
    int16_t signal; 		        //信号强度
    int32_t noise;		            //噪声强度
    uint16_t snr;		            //信噪比
    uint32_t txrate; 		        //理论发送速率
    uint32_t rxrate;  		        //理论接收速率
    uint32_t realTxrate; 	        //真实发送速率
    uint32_t realRxrate; 	        //真实接收速率
    uint16_t txEfficiency;	        //发送效率
    uint32_t frequency;	            //信道频率
    uint32_t txPackets;	            //发送包个数
    uint32_t rxPackets;	            //接收包个数
    uint32_t chload;		        //信道负载
    uint64_t txBytes;		        //发送字节数
    uint64_t rxBytes;		        //接收字节数
    uint32_t txFailed;		        //发送失败次数
    uint32_t txRetries;		        //发送重试次数
    time_t time;                    // 时间戳
} WpaTraff;

typedef struct {
    char domain[32];
    char event[32];
    char field[32];
    uint64_t value;
    time_t time;
} HisyseventData;

typedef struct {
    TraffType traffType;          // 流量类型
    time_t startTime;             // 时间区域
    time_t endTime;               // 时间区域
} CommTraffQueryRule;

typedef struct {
    TraffType traffType;          // 流量类型
    time_t startTime;             // 时间区域
    time_t endTime;               // 时间区域
    int64_t  startRecordIndex;        // 最后一条记录的索引
} CommTraffInnerQueryRule;

// CommTraff 结构体
typedef struct {
    TraffType traffType;                 // 流量类型
    union {
        SessionTraff sessionTraff;       // 会话层流量数据
        TransportTraff transportTraff;   // 传输层流量数据
        LinkTraff linkTraff;             // 链路层流量数据
        RpcTraff rpcTraff;               // RPC
        WpaTraff wpaTraff;               // Wi-Fi流量数据
        HisyseventData hisyseventData;
    } data;
} CommTraff;

typedef struct{
    void (*OnQuery)(CommTraff* records, int32_t nums);
    void (*OnComplete)(int32_t reason, int32_t total);
}CommTraffQueryCb;

typedef struct {
    // app下发的查询条件
    TraffType traffType;          // 流量类型
    time_t startTime;             // 时间区域
    time_t endTime;               // 时间区域
    // 查询结果
    CommTraff *records;
    int32_t  recordNums;             // 查询结果数量
    int64_t  lastRecordIndex;        // 最后一条记录的索引
} CommTraffResult;

// 添加指令消息结构体
typedef struct {
    CommTraffCommandType cmdType;         // 指令类型
    int32_t cPort;
    union {
        CommTraff insertData;             // 插入的数据
        CommTraffInnerQueryRule queryRule;// 查询规则
        CommTraffResult result;           // 查询结果
    } data;
} CommTraffCommand;

/**
 * 插入一条流量数据记录
 * @param record 流量数据记录
 * @return 成功返回0，失败返回负值
 */
int32_t InsertCommTraff(CommTraff *record);

/**
 * @brief 初始化
 * @return 成功返回0，失败返回负值
 */
int32_t CommtraffInit();


/**
 * @brief 注销流程
 * @return 成功返回0，失败返回负值
 */
int32_t CommtraffDeinit();

/**
 * @brief 查询流量数据记录数量
 * @param queryRule  查询条件
 * @return 成功返回0，失败返回负值
 */
int32_t QueryCommTraffNums(CommTraffQueryRule *queryRule);


/**
 * @brief查询流量数据记录,需先执行CommtraffInit()函数, 如果成功返回0，则后续结果通过CommTraffQueryCb通知
 * @param queryRule 查询条件
 * @return 成功返回0，失败返回负值
 */
int32_t QueryCommTraff(CommTraffQueryRule *queryRule, CommTraffQueryCb *cb);

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

#endif //COLLECTD_COMMTRAFF_H
